var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
var config = require('../data/config.json');
var path = require('path');
var Crypto = require('crypto');
var $ = window.$;
var Log = require('./logger');

/**      文件IO类       **/

exports.loadJson = function(file){
	return fs.readFileAsync(file, {encoding:'utf8'}).then(function(content){
		try{
			//去bom
			content = content.replace(/^\uFEFF/, '');
			var raw = JSON.parse(content);
			return Promise.resolve(raw);
		}catch(e){
			return Promise.reject('parse err');
		}
	}).catch(function (e) {
		Log.e("Error in load json:"+file);
		return Promise.reject(e);
	});
};

exports.saveJson = function(file, obj){
	try{
		var raw = JSON.stringify(obj, null, 4);
		return fs.writeFileAsync(file, raw, {encoding:'utf8'});
	}catch(e){
		Log.e("Error in save json:"+file);
		return Promise.reject('parse err');
	}
};

exports.saveJsonSync = function(file, obj){
	try{
		var raw = JSON.stringify(obj, null, 4);
		fs.writeFileSync(file, raw, {encoding:'utf8'});
	}catch(e){
		Log.e("Error in save json:"+file);
	}
};

exports.loadJsonSync = function(file){
	try{
		var raw = fs.readFileSync(file, {encoding:'utf8'});
		if(!raw){
			return null;
		}
		raw = raw.replace(/^\uFEFF/, '');
		return JSON.parse(raw);
	}catch(e){
		return null;
	}
};

exports.loadBase64 = function(file){
	return fs.readFileAsync(file, {encoding:'base64'}).then(function(content){
		return Promise.resolve(content);
	}).catch(function (e) {
		return Promise.reject(e);
	});
};

/**
 * 过滤掉不能在文件名中出现的字符
 * @param name
 */
exports.filterFilename = function(name) {
	return name.replace(/[\*\?\\\/\|<>:"]/g, ' ');
};

/**
 * 确保路径的目录创建
 * @param dir
 */
exports.mkdir = function(dir){
	var arr = dir.split('/');
	var _dir = arr.shift() + '/';
	while(true){
		if(!fs.existsSync(_dir)){
			fs.mkdirSync(_dir);
		}
		if(arr.length > 0){
			_dir = _dir + arr.shift() + path.sep;
		}else{
			break;
		}
	}
};

/**
 * 同步copy
 * 不保证dir
 * @param src
 * @param dest
 * @param force 是否强制覆盖
 */
exports.copyFile = function(src, dest, force, sync) {
	if(!fs.existsSync(src)){
		return;
	}
	if(fs.existsSync(dest)){
		//判断一下size, size相等就认为相同
		var srcStat = fs.statSync(src);
		var destStat = fs.statSync(dest);
		if(srcStat.size == destStat.size && !force){
			return;
		}
	}
	try{
		if(sync){
			fs.writeFileSync(dest, fs.readFileSync(src));
		}else{
			var read = fs.createReadStream(src);
			var write = fs.createWriteStream(dest);
			read.pipe(write);
		}

		return true;
	}catch(e){
		Log.e(e, "copyFile");
	}
	return false;
};

exports.deleteFile = function(file){
	if(!fs.existsSync(file)){
		return;
	}
	fs.unlinkSync(file);
};

exports.fileSize = function (file) {
	if(!fs.existsSync(file)){
		return 0;
	}
	var stat = fs.statSync(file);
	return stat.size;
};

//简易的zip
exports.createZip = function(src, dest){
	var zip = new require('node-zip')();
	var content = fs.readFileSync(src, {encoding:'utf8'});
	if(!content){
		return false;
	}
	zip.file(path.basename(src), content);
	var data = zip.generate({base64:false, type:"nodebuffer", compression:'DEFLATE'});
	if(!data){
		return false;
	}
	fs.writeFileSync(dest, data, 'binary');
	return true;
};

/**
 * 确保路径以某种后缀结尾
 * */
exports.ensureSuffix = function(file, suffix){
	var dir = path.dirname(file);
	var filename = path.basename(file);
	var idx = filename.lastIndexOf('.');
	if(idx > 0){
		filename = filename.substring(0, idx);
	}
	return path.join(dir, filename + '.' + suffix);
};

exports.isDir = function(file){
	var stat = fs.lstatSync(file);
	return stat.isDirectory();
};

/**
 * 如果是目录, 就返回里面的文件
 */
exports.getAllFiles = function(dir){
	var arr = [];
	return fs.readdirAsync(dir).then(function(files){
		files.forEach(function(file){
			var _file = dir + '/' + file;
			_file = _file.replace(/\\/g, '/');
			var stat = fs.lstatSync(_file);
			if(!stat.isDirectory()){
				arr.push(_file);
			}
		});
		return Promise.resolve(arr);
	}).catch(function(e) {
		return Promise.resolve(arr);
	});
};

/**     语言helper类      **/

exports.cloneObject = function(obj){
	if($.isArray(obj)){
		return $.extend(true, [], obj);
	}else{
		return $.extend(true, {}, obj);
	}
};

exports.extendObject = function(parent, obj){
	return $.extend(true, parent, obj);
};

exports.parseIntArray = function(arr) {
	for(var i=0;i<arr.length;i++){
		arr[i] = +arr[i];
	}
	return arr;
};

/**
 * 获得json对象一个深层节点的值, 会判断每一层节点是否存在
 * @param obj
 * @param path
 * @returns {*}
 */
exports.getJsonChainValue = function(obj, chain){
	var arr = chain.split('.');
	var ret = obj;
	while(arr.length){
		var key = arr.shift();
		if(ret[key]){
			ret = ret[key];
		}else{
			return null;
		}
	}
	return ret;
};

exports.setJsonChainValue = function(obj, chain, val){
	var arr = chain.split('.');
	var target = obj;
	while(arr.length){
		var key = arr.shift();
		if(arr.length == 0){
			target[key] = val;
			return;
		}
		if(!target[key]){
			target[key] = {};
		}
		target = target[key];
	}
};

/**
 * 检查JSON链路上的值, 如果不存在, 则赋予默认值
 * @param obj
 * @param chain
 * @param val
 */
exports.ensureJsonValue = function(obj, chain, val){
	var arr = chain.split('.');
	var target = obj;
	while(arr.length){
		var key = arr.shift();
		if(arr.length == 0){
			if(typeof target[key] == 'undefined'){
				target[key] = val;
			}
			return;
		}
		if(!target[key]){
			target[key] = {};
		}
		target = target[key];
	}
};


/***      计算辅助类        **/

/**
 * 提取css bg url
 * @param str
 */
exports.getBackgroundUrl = function(str){
	var match = /url\(([^\)]+)\)/.exec(str);
	if(match){
		var url = match[1];
		if(url.indexOf('file://') == 0){
			url = url.substring(7);
		}
		return url;
	}
	return null;
};

//废弃
exports.stringHash = function (str) {
	var seed = 131;
	var hash = 0;
	for(var i=str.length-1;i>=0;i--){
		hash = hash * seed + str.charCodeAt(i);
	}
	return hash & 0x7FFFFFFF;
};

exports.md5 = function(str) {
	return Crypto.createHash('md5').update(str).digest('hex');
};

exports.fileMd5 = function (file) {
	var hash = Crypto.createHash('md5');
	var stream = fs.createReadStream(file);
	var defer = Promise.defer();
	stream.on('data', function (data) {
		hash.update(data, 'utf8')
	});

	stream.on('end', function () {
		defer.resolve(hash.digest('hex'));
	});

	stream.on('error', function(){
		defer.reject();
	});

	return defer.promise;
};

/***
 * 把毫秒数变成00:00.000的格式
 */
exports.getFormatTime = function(time){
	var sign = time < 0 ? '-' : '';
	time = Math.abs(Math.round(time));
	var mile = time % 1000;
	if(mile < 10){
		mile = '00'+mile;
	}else if(mile < 100){
		mile = '0'+mile;
	}
	time = Math.floor(time / 1000);
	var sec = time % 60;
	if(sec < 10){
		sec = '0'+sec;
	}
	time = Math.floor(time / 60);
	if(time < 10){
		time = '0'+time;
	}
	return sign + time + ':' + sec + '.' + mile;
};

exports.getFormatSize = function (size) {
	if(size < 1024){
		return size + 'b';
	}
	size /= 1024;
	if(size < 1024){
		return size.toFixed(1) + 'Kb';
	}
	size /= 1024;
	return size.toFixed(1) + 'Mb';
};

exports.formatStr = function(str, arr){
	str = str.replace(/({(\d+)})/g,function($0,$1,$2){
		if(typeof arr[$2] == 'undefined'){
			return '';
		}
		return arr[$2];
	});
	return str;
};

exports.lerp = function(minVal, maxVal, curr, len){
	if(len == 0){
		return 0;
	}
	var val = (curr / len) * (maxVal - minVal) + minVal;
	if(val < minVal){
		return minVal;
	}else if(val > maxVal){
		return maxVal;
	}else{
		return val;
	}
};

exports.clamp = function(val, min, max){
	if(val < min){
		return min;
	}else if(val > max){
		return max;
	}
	return val;
};
/**
 * 二分查找
 * fn 返回-1 表示目标节点小于比较节点
 * 返回完全相等的节点
 * @param arr
 * @param fn
 * @returns {*}
 */
exports.binaryFind = function(arr, fn, returnIndex){
	var left = 0,
		right = arr.length,
		index = (left + right) >>> 1,
		r = 0;
	while (left < right){
		var item = arr[index];
		r = fn(item);
		if (r == 0) {
			return returnIndex ? index : item;
		} else if(r > 0){
			left = index + 1;
		}else{
			right = index;
		}
		index = (left + right) >>> 1;
	}
	return null;
};

/**
 * 返回最后一个小于等于目标节点的序号
 * @param arr
 * @param fn
 * @returns {*}
 */
exports.binaryFindIndex = function (arr, fn) {
	var left = 0,
		right = arr.length,
		index = (left + right) >>> 1,
		r = 0;
	while (left < right){
		r = fn(arr[index]);
		if (r >= 0){
			left = index + 1;
		}else{
			right = index;
		}
		index = (left + right) >>> 1;
	}
	return left - 1;
};


/**      业务相关    **/

/**
 * 返回程序特殊路径用 - 内部文件用
 * @param key
 */
exports.getPath = function(key){
	if(!config[key]){
		return null;
	}
	if(config[key][0] != '.'){
		return config[key];
	}
	var dir = __dirname;  // /util
	config[key] = path.resolve(dir, config[key]);
	return config[key];
};

/**
 * 返回工作目录
 * @param file
 */
exports.getWorkingPath = function(file){
	var dir = path.dirname(process.execPath);
	return path.resolve(dir, file);
};

/**
 * 获得当前目录下无扩展名的文件映射
 * 如a.mp3 => a: a.mp3
 * @param _dir
 */
exports.getFileMapping = function(_dir){
	var files = fs.readdirSync(_dir);
	var fileMapping = {};
	for(var i=0;i<files.length;i++){
		var realName = files[i];
		var name = realName.toLocaleLowerCase();
		var ext = path.extname(name);
		fileMapping[path.basename(name, ext)] = realName;

	}
	return fileMapping;
};

/**
 * 去掉文件的扩展名 获得一个小写的结果
 * @param fn
 */
exports.lowerCaseRemoveExt = function(fn){
	var name = fn.toLocaleLowerCase();
	var ext = path.extname(name);
	return path.basename(name, ext);
};